#include "ds/loop_queue.h"
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>

LoopQueue_t *createLoopQueue(int capacity)
{
    LoopQueue_t *queue = (LoopQueue_t *)malloc(sizeof(LoopQueue_t));
    if (queue == NULL)
    {
        return NULL;
    }

    queue->front = 0;
    queue->rear = 0;
    queue->capacity = capacity;
    queue->size = 0;
    queue->array = (int **)malloc(capacity * sizeof(int *));
    if (queue->array == NULL)
    {
        free(queue);
        return NULL;
    }

    for (int i = 0; i < capacity; i++)
    {
        queue->array[i] = NULL; // 每个array[i]都是一个指针，初始化为NULL
    }

    return queue;
}

void destroyLoopQueue(LoopQueue_t *queue)
{
    if (queue == NULL)
    {
        return;
    }

    for (int i = 0; i < queue->capacity; i++)
    {
        if (queue->array[i] != NULL)
        {
            free(queue->array[i]);
        }
    }

    free(queue->array);
    free(queue);
}

int *enqueueLoop(LoopQueue_t *queue, int *element)
{
    if (queue == NULL || isFull(queue))
    {
        return NULL;
    }

    queue->array[queue->rear] = element;
    queue->rear = (queue->rear + 1) % queue->capacity;
    queue->size++;

    return element;
}

int *dequeueLoop(LoopQueue_t *queue)
{
    if (queue == NULL || isEmpty(queue))
    {
        return NULL;
    }

    int *element = queue->array[queue->front];
    queue->array[queue->front] = NULL;
    queue->front = (queue->front + 1) % queue->capacity;
    queue->size--;

    return element;
}

int *front(LoopQueue_t *queue)
{
    if (queue == NULL || isEmpty(queue))
    {
        return NULL;
    }

    return queue->array[queue->front];
}

int *rear(LoopQueue_t *queue)
{
    if (queue == NULL || isEmpty(queue))
    {
        return NULL;
    }

    return queue->array[(queue->rear - 1 + queue->capacity) % queue->capacity];
}

int isEmpty(LoopQueue_t *queue)
{
    if (queue == NULL)
    {
        return 1;
    }

    return queue->size == 0;
}

int isFull(LoopQueue_t *queue)
{
    if (queue == NULL)
    {
        return 0;
    }

    return queue->size == queue->capacity;
}
